﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.Text.RegularExpressions;
using game;
using game.character;
using game.character.battle;
using game.character.bullet;
using game.character.enemy;
using game.character.weapon;
using game.display;
using game.display.effect;
using game.display.hud;
using game.display.object2d;
using game.scene;
using lumo;
using lumo.display;
using lumo.display.animation2D;
using lumo.display.gui;
using lumo.display.light;
using lumo.display.object2D;
using lumo.input;
using lumo.scene;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Storage;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Contacts;
using FarseerPhysics.Factories;

namespace game.display.object2d
{

    public class Bar
    {

        protected float _Start;
        protected float _Current;
        protected float _End;

        protected Sprite[] _Sprites;
        public Sprite[] Sprites { get { return _Sprites; } }

        public float Start
        {
            get { return _Start; }
            set
            {
                float oldValue = _Start;
                _Start = MathHelper.Clamp(value, 0, _End - 1);

                if (_Start == oldValue)
                    return;

                _Current = MathHelper.Clamp(_Current, _Start, _End);
                Refresh();
            }
        }

        public float Current
        {
            get { return _Current; }
            set
            {
                float oldValue = _Current;
                _Current = MathHelper.Clamp(value, _Start, _End);

                if (_Current != oldValue)
                    Refresh();
            }
        }

        public float End
        {
            get { return _End; }
            set
            {
                float oldValue = _End;
                _End = MathHelper.Clamp(value, 0, float.MaxValue);

                if (_End == oldValue)
                    return;

                _Start = MathHelper.Clamp(_Start, 0, _End - 1);
                _Current = MathHelper.Clamp(_Current, _Start, _End);

                Refresh();
            }
        }

        public Sprite Background
        {
            get { return _Sprites[0]; }
            set { _Sprites[0] = value; }
        }

        public Sprite BarSprite
        {
            get { return _Sprites[1]; }
            set { _Sprites[1] = value; }
        }

        public Sprite Cover
        {
            get { return _Sprites[2]; }
            set { _Sprites[2] = value; }
        }

        public CropAnimation2D _Animation;

        public Bar(Texture2D background, Texture2D bar, Texture2D cover)
        {
            _Sprites = new Sprite[3] {
                new Sprite(background),
                new Sprite(bar),
                new Sprite(cover)
            };
        }

        public void Setup(float start, float current, float end)
        {
            _End = MathHelper.Clamp(_End, 0, float.MaxValue);
            _Start = MathHelper.Clamp(_Start, 0, _End - 1);
            _Current = MathHelper.Clamp(_Current, _Start, _End);

            int x = (int)((1 - _Current / (_End - _Start)) * BarSprite.Texture.Width);
            BarSprite.SourceRectangle = new Rectangle(x, 0, BarSprite.Texture.Width - x, BarSprite.Texture.Height);

            _Animation = null;
        }

        public void Refresh()
        {
            int x = (int)((1 - _Current / (_End - _Start)) * BarSprite.Texture.Width);

            _Animation = new CropAnimation2D(
                new Rectangle(x, 0, BarSprite.Texture.Width - x, BarSprite.Texture.Height),
                1000.0f,
                Smooth.Arrival,
                Loop.None,
                BarSprite
            );
        }

        public void Update(LumoComponent component)
        {
            if (_Animation == null)
                return;
            _Animation.Update(component);
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            for (int i = 0; i < _Sprites.Length; i++)
                _Sprites[i].Draw(spriteBatch);
        }

    }

}